home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Languguage OS 2
/
Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO
/
gnu
/
objcissu.lha
/
loadModules
< prev
next >
Wrap
Text File
|
1993-03-01
|
8KB
|
304 lines
Newsgroups: comp.sys.next.programmer
From: mauriti@cs.tu-berlin.de (Frank Hartlep)
Subject: Re: Loading classes at run-time: How?
Organization: Technical University of Berlin, Germany
Date: Mon, 21 Sep 1992 13:14:22 GMT
Here's the promised code for loading/unloading classes in a
random order. This means that sets of classes loaded
with objc_loadModules() do not need to be unloaded in reverse
order - unload them as you like. Just take care not to unload
a class if subclasses are still around. Two notes on loading:
when loading a set of classes the name of a class must
precede the names of its subclasses in the file list,
otherwise the load will fail; objc_loadModules will also load
non-class object files.
The C code is a snippet of my original code. I hope I haven't
introduced any errors (I haven't tested it, but it compiled well).
LoadModules() loads all the object or archive files in alphabetic
order in a directory of your choice. It just uses plain old
objc_loadModules. UnloadClasses() unloads the class set associated
with a given mach header. If you're wondering why I'm giving you
assembler code: The code is a patched version of objc_unloadModules().
I only changed two things: 1. Instead of obtaining a mach header by
calling rld_current_header it now uses the one passed as argument,
and 2. it doesn't call rld_unload anymore before finishing.
After trying many things this is still the best solution
I could think of.
I've tried the code quite a few times, and so far no errors
showed up. What I don't know is if the code handles categories
correctly. If you find any bugs, please let me know.
Btw, NextAnswers misc.567 was of great help. Read it, if you haven't.
Frank
__________
#include <libc.h>
#include <objc/objc-load.h>
#include <cthreads.h>
#include <rld.h>
#include <stdio.h>
#include <string.h>
#include <sys/dir.h>
#include <sys/param.h>
extern int UnloadClasses (
struct mach_header *, NXStream *, void (*) (Class, Category));
static void ToSeeIsToBelieve(
Class LoadedClass,
Category LoadedCategory)
{
if (LoadedCategory != NULL)
printf (
"class = %s, category = %s\n",
LoadedCategory->class_name,
LoadedCategory->category_name);
else
printf ("class = %s\n", LoadedClass->name);
return;
}
static int IsObjectOrArchiveFile (
struct direct *File)
{
char *Extension;
Extension = rindex (File->d_name, '.');
return Extension != NULL && (! strcmp (Extension, ".o") ||
! strcmp (Extension, ".a"));
}
int LoadModules (
char *WhereToLoadFrom,
struct mach_header **MachHeader,
vm_size_t *RegionSize)
{
NXStream *ErrorStream;
char *OutputFile = "rld.gdb";
boolean_t Shared;
char Cwd [MAXPATHLEN + 1],
**LoadFiles;
int IsBadLoad, Files, i;
port_t ObjectName;
struct direct **ToBeLoaded;
vm_address_t Region;
vm_inherit_t Inheritance;
vm_offset_t Offset;
vm_prot_t Protection, MaxProtection;
ErrorStream = NXOpenFile (fileno (stderr), NX_WRITEONLY);
getwd (Cwd);
if (chdir (WhereToLoadFrom) == -1) {
NXPrintf (ErrorStream, "no such directory\n");
goto Error;
}
LoadFiles = (char **) malloc (1);
Files = scandir (".", &ToBeLoaded, IsObjectOrArchiveFile, alphasort);
for (i = 0; i < Files; i ++) {
LoadFiles = (char **) realloc (
LoadFiles, (i + 2) * sizeof (char *));
LoadFiles [i] = ToBeLoaded [i]->d_name;
}
LoadFiles [i] = NULL;
printf ("Loading ...\n");
IsBadLoad = objc_loadModules (
LoadFiles, ErrorStream, ToSeeIsToBelieve,
MachHeader,OutputFile);
for (i = 0; i < Files; i ++)
free (ToBeLoaded [i]);
free (ToBeLoaded);
chdir (Cwd);
if (IsBadLoad)
goto Error;
Region = (vm_address_t) *MachHeader;
vm_region (
task_self (), &Region, RegionSize,
&Protection, &MaxProtection, &Inheritance,
&Shared, &ObjectName, &Offset);
if (! rld_unload_all (ErrorStream, 0))
goto Error;
NXClose (ErrorStream);
return 0;
Error:
NXClose (ErrorStream);
return -1;
}
void UnloadClassesAndFree (
struct mach_header *MachHeader,
vm_size_t RegionSize)
{
printf ("Unloading ...\n");
UnloadClasses (MachHeader, NULL, ToSeeIsToBelieve);
vm_deallocate (
task_self (),(vm_address_t) MachHeader,RegionSize);
return;
}
__________
#NO_APP
.set _send_unload_message_to_category,0x05033c76
.set _send_unload_message_to_class,0x05033cbe
.set __objc_remove_category,0x050322cc
.set __sel_unloadSelectors,0x5032534
.cstring
LC0:
.ascii "__OBJC\0"
LC1:
.ascii "__module_info\0"
LC2:
.ascii "__selector_strs\0"
.text
.even
.globl _UnloadClasses
_UnloadClasses:
linkw a6,#-8
moveml d2/d3/d4/d5/d6/d7/a2/a3/a4,sp@-
movel a6@(12),a4
movel a6@(16),a3
movel a6@(8),d5
pea a6@(-4)
pea LC1:l
pea LC0:l
movel d5,sp@-
jsr _getsectdatafromheader
movel d0,a2
movel a2,d7
movel a6@(-4),d6
addw #16,sp
tstl a2
jeq L2
tstl d6
jeq L2
clrl d4
L10: movel a2@(12),a0
movew a0@(8),d4
movel d4,d2
clrl d3
bras L3
L5: tstl a3
beqs L4
movel a2@(12),a0
movel a0@(12:b,d2:l:4),sp@-
movel a0@(12:b,d2:l:4),a0
movel a0@(4),sp@-
jsr _objc_getClass
addqw #4,sp
movel d0,sp@-
jsr a3@
addqw #8,sp
L4: movel a2@(12),a0
movel a0@(12:b,d2:l:4),sp@-
jsr _send_unload_message_to_category
addqw #4,sp
addql #1,d2
L3: movel a2@(12),a0
movew a0@(8),d3
movew a0@(10),d4
movel d3,d0
addl d4,d0
cmpl d2,d0
bgts L5
clrl d2
clrl d3
bras L6
L8: tstl a3
beqs L7
clrl sp@-
movel a2@(12),a0
movel a0@(12:b,d2:l:4),sp@-
jsr a3@
addqw #8,sp
L7: movel a2@(12),a0
movel a0@(12:b,d2:l:4),sp@-
jsr _send_unload_message_to_class
addqw #4,sp
addql #1,d2
L6: movel a2@(12),a0
movew a0@(8),d3
cmpl d2,d3
bgts L8
movel a6@(-4),d0
subl a2@(4),d0
movel d0,a6@(-4)
beqs L9
addl a2@(4),a2
L9: tstl a6@(-4)
jne L10
movel d7,a2
movel d6,a6@(-4)
L16: movel a2@(12),a0
clrl d0
movew a0@(8),d0
movel d0,d2
clrl d4
clrl d3
bras L11
L12: movel a2@(12),a0
movel a0@(12:b,d2:l:4),sp@-
jsr __objc_remove_category
addqw #4,sp
addql #1,d2
L11: movel a2@(12),a0
movew a0@(8),d4
movew a0@(10),d3
movel d4,d0
addl d3,d0
cmpl d2,d0
bgts L12
clrl d2
clrl d3
bras L13
L14: movel a2@(12),a0
movel a0@(12:b,d2:l:4),sp@-
jsr _objc_getClasses
movel d0,sp@-
jsr _NXHashRemove
addqw #8,sp
addql #1,d2
L13: movel a2@(12),a0
movew a0@(8),d3
cmpl d2,d3
bgts L14
movel a6@(-4),d0
subl a2@(4),d0
movel d0,a6@(-4)
beqs L15
addl a2@(4),a2
L15: tstl a6@(-4)
bnes L16
pea a6@(-8)
pea LC2:l
pea LC0:l
movel d5,sp@-
jsr _getsectdatafromheader
movel d0,d1
addl a6@(-8),d1
movel d1,sp@-
movel d0,sp@-
jsr __sel_unloadSelectors
clrl d0
L2: moveml a6@(-44),d2/d3/d4/d5/d6/d7/a2/a3/a4
unlk a6
rts